import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Button, Form, Field, Message, Balloon } from '@teamix/ui';
import BalloonConfirm from 'components/ballonConfirm';
import { ORGANIZATION_ADMIN_ROLES } from 'utils/constants.js';
import { getPathWithRootPath } from 'utils/router';
import DeletePathResourceDialog from 'components/deletePathResourceDialog';
import debounce from 'lodash.debounce';
import { checkGroupNamePath, checkCanTranfer, getEncryptedProjectsInGroup } from 'api/index.js';
import { access } from 'components/accessContainer/util';
import AddonBeforeInput from 'components/addonBeforeInput';
import GroupSelect from 'components/groupSelect';
import RepoDialog from 'components/encryptedProjectsDialog';
import intl from '../../../../../../../../../../locale';

const { Tooltip } = Balloon;

// id通过force取得
const { pathResource, organization } = window.FORCE;
const { user_role } = organization;

// 拥有者和企业管理员有权限转移
// const hasAuth = ['ORG_ADMIN', 'ORG_OWNER ', 'ADMIN'].indexOf(organization.user_role) > -1;

const FormItem = Form.Item;

export default class DangerousForm extends Component {
  static propTypes = {
    searchNamespaces: PropTypes.func,
    transfer: PropTypes.func,
    rename: PropTypes.func,
    name: PropTypes.string,
    path: PropTypes.string,
    fullName: PropTypes.string,
    httpUrl: PropTypes.string,
    removeConfirmVisible: PropTypes.bool,
    removeConfirmContent: PropTypes.string,
    removeButtonDisabled: PropTypes.bool,
    isRemoving: PropTypes.bool,
    isTransferring: PropTypes.bool,
    remove: PropTypes.func,
  };

  static defaultProps = {
    transfer: () => {},
    searchNamespaces: () => {},
    rename: () => {},
    remove: () => {},
    name: '',
    path: '',
    fullName: '',
    httpUrl: '',
    removeConfirmVisible: false,
    removeConfirmContent: null,
    removeButtonDisabled: true,
    isRemoving: false,
    isTransferring: false,
  };

  constructor(props) {
    super(props);
    this.renameField = new Field(this);
    this.transferField = new Field(this);
    this.state = {
      namespaces: [],
      // 将要转移移到的代码组ID
      target_id: '',
      target_path: '',
      isLoadingEncryptedProjects: true,
      // 组下加密库列表
      encryptedProjects: [],
      isModalOpen: false,
      encryptedProjectsCount: 0,
    };

    this.checkPath = debounce(this.checkPath, 500);
    this.onNamespaceSearch = debounce(this.onNamespaceSearch.bind(this), 500);
  }

  componentDidMount() {
    // 获取企业下拉数据
    this.props.searchNamespaces('', (result) => {
      const { list } = result;
      this.setState({ namespaces: list });
    });
    this.props.getGroupSettingData();
    this.getEncryptedProjects();
  }

  getEncryptedProjects = () => {
    getEncryptedProjectsInGroup(
      { groupId: pathResource.id },
      {
        per_page: 10,
        page: 1,
      },
    )
      .then((result) => {
        const [amountInfo, ...list] = result;
        this.setState({
          isLoadingEncryptedProjects: false,
          encryptedProjects: list || [],
          encryptedProjectsCount: amountInfo.amount || 0,
        });
      })
      .catch((err) => {
        console.error(err);
        this.setState({
          isLoadingEncryptedProjects: false,
        });
      });
  };

  onNamespaceSearch(value) {
    this.props.searchNamespaces(value, (result) => {
      this.setState({ namespaces: result.list });
    });
  }

  getPathPrefix = (httpUrl) => {
    return httpUrl ? `${httpUrl.match(/(.+)\/(.+)/)[1]}/` : httpUrl;
  };

  getNewFullPath = (httpUrl) => {
    const prefix = httpUrl ? `${httpUrl.match(/(.+)\/(.+)/)[1]}/` : httpUrl;
    const path = this.renameField.getValue('path');
    return prefix + path;
  };

  checkPath(value, callback) {
    checkGroupNamePath({ path: value, namespace_id: pathResource.parentId })
      .then(() => {
        callback();
      })
      .catch((err) => {
        if (err.responseText) {
          const errCause = JSON.parse(err.responseText).cause;
          callback(`${errCause}`);
        } else {
          throw err;
        }
      });
  }

  pathValidator = (rule, value, callback) => {
    const { path } = this.props;
    if (!value || value === path) {
      callback();
      return;
    }
    if (/^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,}$/.test(value)) {
      this.checkPath(value, callback);
    } else {
      callback(
        intl.get({
          id: 'code-assets.containers.dangerousForm.ItCanOnlyContainLetters',
          defaultMessage: "只能包含字母和数字、 '_'、 '.'和'-'，且只能以字母、数字或'_'开头",
        }),
      );
    }
  };

  rename = (cb) => {
    this.renameField.validate((errors) => {
      if (!errors) {
        const formData = this.renameField.getValues();
        // formData.name = this.props.name;
        this.props.rename(formData, (data) => {
          cb(data);
        });
      }
    });
  };

  transfer = (callback) => {
    const { target_id, target_path } = this.state;
    if (!target_id) {
      Message.warning({
        title: intl.get({
          id: 'code-assets.containers.dangerousForm.SelectACodeGroup',
          defaultMessage: '请选择代码组',
        }),
      });

      return;
    }
    this.props.transfer({ target_id, target_path }, callback);
  };

  getFullNameWithoutOrg = (path) => {
    const arr = path.split('/');
    const { length } = arr;
    return arr[length - 1] ? arr[length - 1].trim() : '';
  };

  setSelectNamespace = (item) => {
    console.log(item);
    this.setState({
      target_id: item.value,
      target_path: item.path_with_namespace,
    });
  };

  namespaceValidator = (rule, value, callback) => {
    checkCanTranfer({
      namespace_id: Number(value),
      group_id: pathResource.id,
    })
      .then(() => {
        callback();
      })
      .catch((err) => {
        if (err.responseText) {
          const errCause = JSON.parse(err.responseText).cause;
          callback(`${errCause}`);
        } else {
          throw err;
        }
      });
  };

  renderDeleteBtn = (name, isAllowAdminDelete) => {
    const { isLoadingEncryptedProjects, encryptedProjects, encryptedProjectsCount, isModalOpen } =
      this.state;
    const trigger = (
      <Button type="primary" warning disabled>
        {intl.get({ id: 'code-assets.containers.dangerousForm.Delete', defaultMessage: '删除' })}
      </Button>
    );

    if (isLoadingEncryptedProjects) {
      return trigger;
    }
    if (encryptedProjects.length > 0) {
      return (
        <>
          <Balloon
            trigger={trigger}
            closable={false}
            popupStyle={{
              width: 320,
              maxWidth: 'none',
            }}
            popupProps={{
              className: 'encrypto-tooltip-popup',
            }}
            align="tl"
          >
            <div>
              <div>代码组存在已加密子库，暂不允许删除，请关闭子库「仓库加密」后再试。</div>
              <Button
                type="primary"
                text
                style={{ marginTop: 10 }}
                onClick={() => {
                  this.setState({
                    isModalOpen: true,
                  });
                }}
              >
                {intl.get({
                  id: 'code-assets.containers.dangerousForm.ViewTheListOfEncrypted',
                  defaultMessage: '查看已加密子库列表',
                })}
              </Button>
            </div>
          </Balloon>
          {isModalOpen && (
            <RepoDialog
              isGroup
              groupId={pathResource.id}
              initialList={encryptedProjects}
              total={encryptedProjectsCount}
              isModalOpen={isModalOpen}
              closeModal={() => {
                this.setState({
                  isModalOpen: false,
                });
              }}
            />
          )}
        </>
      );
    }

    if (!access(ORGANIZATION_ADMIN_ROLES, user_role) && !isAllowAdminDelete) {
      return (
        <Tooltip
          trigger={
            <Button type="primary" warning disabled>
              {intl.get({
                id: 'code-assets.containers.dangerousForm.Delete',
                defaultMessage: '删除',
              })}
            </Button>
          }
          align="t"
        >
          {intl.get({
            id: 'code-assets.containers.dangerousForm.TheEnterpriseRestrictionGroupAdministrator',
            defaultMessage: '企业限制组管理员删除代码组，请联系企业管理员处理',
          })}
        </Tooltip>
      );
    }

    return (
      <DeletePathResourceDialog
        type={'group'}
        name={name}
        trigger={
          <Button type="primary" warning>
            {intl.get({
              id: 'code-assets.containers.dangerousForm.Delete',
              defaultMessage: '删除',
            })}
          </Button>
        }
      />
    );
  };

  render() {
    const renameInit = this.renameField.init;
    const transferInit = this.transferField.init;
    const { path, httpUrl, name, groupAdminOperation } = this.props;
    const { target_path, namespaces } = this.state;
    const namespaceDatabase = [];

    // 公有云转移展示 多级组展示的是路径 TODO
    namespaces.forEach((item) => {
      item.id !== Number(pathResource.id) &&
        namespaceDatabase.push({
          label: this.getFullNameWithoutOrg(item.path_with_namespace),
          value: item.id,
        });
    });

    const { fullPath } = pathResource;
    const pathArr = fullPath.split('/');
    const pathChange = pathArr[pathArr.length - 1] !== this.renameField.getValue('path');
    const transferDisabled =
      !this.transferField.getValue('namespace_id') ||
      this.transferField.getValue('namespace_id') === Number(pathResource.id) ||
      this.transferField.getError('namespace_id') !== null;
    // FIXME 后端接口要改加上标志位 这啥玩意。组这里只有一个删除受控，值1是允许管理员删除。先这么判断吧
    const isAllowAdminDelete = groupAdminOperation && groupAdminOperation.some((v) => v === 1);

    const newFullPath = this.getNewFullPath(httpUrl);
    return (
      <div className="dangerous-form">
        <div className="setting-card-body">
          <div className="change-path setting-card-item">
            <div className="setting-card-subtitle">
              {intl.get({
                id: 'code-assets.containers.dangerousForm.CodeGroupPathModification',
                defaultMessage: '代码组路径修改',
              })}
            </div>
            <div className="setting-card-subtitle-desc">
              {intl.get({
                id: 'code-assets.containers.dangerousForm.TheNameAndPathOf',
                defaultMessage:
                  '代码组的名称和路径是不同的概念，会影响开发人员实际操作及访问，导致原克隆地址不可用',
              })}
            </div>
            <div className="setting-card-action">
              <Form inline field={this.renameField}>
                <FormItem label="" className="no-mr-b">
                  <AddonBeforeInput
                    addonTextBefore={this.getPathPrefix(httpUrl)}
                    {...renameInit('path', {
                      initValue: path,
                      rules: [
                        {
                          required: true,
                          message: intl.get({
                            id: 'code-assets.containers.dangerousForm.ThisParameterIsRequired',
                            defaultMessage: '该项为必填项',
                          }),
                        },

                        {
                          validator: this.pathValidator,
                        },
                      ],
                    })}
                    placeholder={intl.get({
                      id: 'code-assets.containers.dangerousForm.EnterTheCodeGroupPath',
                      defaultMessage: '请输入代码组路径',
                    })}
                    className="path-input"
                    // style={{ width: 320 }}
                  />
                </FormItem>
                <FormItem label="" className="no-mr-b">
                  {pathChange ? (
                    <BalloonConfirm
                      type="warning"
                      align="br"
                      title={intl.get({
                        id: 'code-assets.containers.dangerousForm.ConfirmModification',
                        defaultMessage: '确认修改',
                      })}
                      content={intl.get(
                        {
                          id: 'code-assets.containers.dangerousForm.ChangeTheGroupPathTo',
                          defaultMessage: '确认修改组路径为 {newFullPath}',
                        },
                        { newFullPath },
                      )}
                      triggerType="click"
                      size="large"
                      trigger={
                        <Button type="primary" warning style={{ display: 'inline-block' }}>
                          {intl.get({
                            id: 'code-assets.containers.dangerousForm.Modify',
                            defaultMessage: '修改',
                          })}
                        </Button>
                      }
                      okFn={this.rename}
                      followTrigger
                    />
                  ) : (
                    <Button type="primary" warning disabled style={{ display: 'inline-block' }}>
                      {intl.get({
                        id: 'code-assets.containers.dangerousForm.Modify',
                        defaultMessage: '修改',
                      })}
                    </Button>
                  )}
                </FormItem>
              </Form>
            </div>
          </div>

          <div className="transfer-project setting-card-item">
            <div className="setting-card-subtitle">
              {intl.get({
                id: 'code-assets.containers.dangerousForm.TransferCodeGroup',
                defaultMessage: '转移代码组',
              })}
            </div>
            <div className="setting-card-subtitle-desc">
              {intl.get({
                id: 'code-assets.containers.dangerousForm.TransferringACodeGroupAffects',
                defaultMessage:
                  '转移代码组会影响开发人员实际操作及访问，导致源克隆地址不可用。转移后，需要更新本地仓库地址，指向新的地址',
              })}
            </div>
            <div className="setting-card-action">
              <Form inline field={this.transferField}>
                <FormItem label="" className="no-mr-b">
                  <GroupSelect
                    okFn={this.setSelectNamespace}
                    style={{ width: '300px', height: '40px' }}
                    // 这是代码组设置页中的转移代码组部分
                    autoWidth
                    isFilterSelf
                    operateType={'transfer'}
                    type={'group'}
                    popupProps={{
                      // align: 'tl bl',
                      align: 'bl tl',
                    }}
                    {...transferInit('namespace_id', {
                      rules: [
                        {
                          validator: this.namespaceValidator,
                        },
                      ],
                    })}
                    isTransfer
                  />
                </FormItem>
                <FormItem label="" className="no-mr-b">
                  {!transferDisabled ? (
                    <BalloonConfirm
                      type="warning"
                      align="tl"
                      title={intl.get({
                        id: 'code-assets.containers.dangerousForm.ConfirmTransfer',
                        defaultMessage: '确认转移',
                      })}
                      content={`确认要转移到 ${window.location.origin}${getPathWithRootPath(
                        target_path,
                      )} 吗？`}
                      triggerType="click"
                      size="large"
                      trigger={
                        <Button type="primary" warning style={{ display: 'inline-block' }}>
                          {intl.get({
                            id: 'code-assets.containers.dangerousForm.Transfer',
                            defaultMessage: '转移',
                          })}
                        </Button>
                      }
                      okFn={this.transfer}
                      followTrigger
                    />
                  ) : (
                    <Button type="primary" warning disabled style={{ display: 'inline-block' }}>
                      {intl.get({
                        id: 'code-assets.containers.dangerousForm.Transfer',
                        defaultMessage: '转移',
                      })}
                    </Button>
                  )}
                </FormItem>
              </Form>
            </div>
          </div>

          <div className="delete-group setting-card-item">
            <div className="setting-card-content">
              <div className="setting-card-content-left">
                <div className="setting-card-subtitle">
                  {intl.get({
                    id: 'code-assets.containers.dangerousForm.DeleteACodeGroup',
                    defaultMessage: '删除代码组',
                  })}
                </div>
                <div className="setting-card-subtitle-desc">
                  {intl.get({
                    id: 'code-assets.containers.dangerousForm.TheCodeGroupWillBe',
                    defaultMessage:
                      '代码组将移入回收站，数据最长保留15天，此期间支持手动恢复，超期后数据将彻底删除，彻底删除后不可恢复',
                  })}
                </div>
              </div>
              <div className="setting-card-content-right">
                {this.renderDeleteBtn(name, isAllowAdminDelete)}
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
}
